﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Marbles.Core.Authentication;
using Marbles.Core.Content.Pages;
using Marbles.Core.Pages;
using System.IO;

namespace Marbles.Web.Admin
{
    public partial class Explorer : Core.Pages.AdminPage
    {

        public int ColumnCount
        {
            get { object obj = Request.Params["cols"]; return (obj == null ? 4 : Convert.ToInt32(obj)); }
        }

        protected override void OnPreInit(EventArgs e)
        {
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            AuthenticationProvider prov = AuthenticationProvider.CreateProviderInstance();
            if (!prov.IsAuthenticated) { Response.Redirect("Default.aspx", true); }

            if (!string.IsNullOrEmpty(this.cCurrentDir.Value)) { PopulateFiles(this.cCurrentDir.Value); }

            if (!Page.IsPostBack)
            {
                InitialiseForm();
            }

        }

        private void InitialiseForm()
        {
            cViewDirs.Nodes.Clear();
            string path = HttpContext.Current.Server.MapPath("/");
            TreeNode node = new TreeNode();
            node.Value = path;
            node.Text = "/";
            PopulateTree(node, path);
            cViewDirs.Nodes.Add(node);
            node.Selected = true;
            node.Expand();
            PopulateFiles(path);
        }

        private string GetPath()
        {
            TreeNode node = cViewDirs.SelectedNode;
            string path = string.Empty;

            if (node == null) { return ""; }

            do
            {
                if (node.Text.StartsWith("/"))
                {
                    path = node.Text + path;
                }
                else
                {
                    path = "/" + node.Text + path;
                }
                node = node.Parent;
            }
            while (node != null);

            path = path.Replace("//", "/");
            return path;
        }

        private void PopulateFiles(string path)
        {

            cCurrentDir.Value = path;
            string path1 = GetPath();
            if (!string.IsNullOrEmpty(GetPath())) { cLblPath.Text = path1; }

            cTblFiles.RepeatColumns = ColumnCount;
            cTblFiles.RepeatDirection = RepeatDirection.Horizontal;
            cTblFiles.DataSource = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly);
            cTblFiles.DataBind();

        }

        protected void File_Command(object sender, CommandEventArgs e)
        {
            string filename = Path.Combine(cCurrentDir.Value, e.CommandArgument.ToString());
            FileInfo info = new FileInfo(filename);

            cLblLoc.Text = info.DirectoryName;
            cLblName.Text = info.Name;

            cLblAttributes.Text = "";

            foreach (object value in Enum.GetValues(typeof(FileAttributes)))
            {
                if ((info.Attributes & ((FileAttributes)value)) != 0)
                {
                    if (!string.IsNullOrEmpty(cLblAttributes.Text)) { cLblAttributes.Text += ", "; }
                    cLblAttributes.Text += Enum.GetName(typeof(FileAttributes), value);
                }
            }

            cLblMBSize.Text = ((info.Length / 1024) / 1024).ToString() + " mb";
            cLblSize.Text = info.Length.ToString() + " bytes";
            cChkReadonly.Checked = info.IsReadOnly;
            cLblCreated.Text = info.CreationTime.ToLongDateString() + " " + info.CreationTime.ToLongTimeString();
            cLblLastAccess.Text = info.LastAccessTime.ToLongDateString() + " " + info.LastAccessTime.ToLongTimeString();
            cLblLastWritten.Text = info.LastWriteTime.ToLongDateString() + " " + info.LastWriteTime.ToLongTimeString();
            cDlgFileInfo.Visible = true;
            cBtnInfoDelete.CommandArgument = filename;
            cBtnInfoView.CommandArgument = filename;
        }

        private void PopulateTree(TreeNode parent, string path)
        {
            foreach (string directory in Directory.GetDirectories(path, "*.*", SearchOption.TopDirectoryOnly))
            {
                TreeNode node = new TreeNode();
                DirectoryInfo info = new DirectoryInfo(directory);
                node.Value = info.FullName;
                node.Text = info.Name;
                node.Expanded = false;

                PopulateTree(node, info.FullName);

                if (parent == null)
                {
                    cViewDirs.Nodes.Add(node);
                }
                else { parent.ChildNodes.Add(node); }
            }
        }

        protected void cViewDirs_NodeExpand(object sender, TreeNodeEventArgs e)
        {
            PopulateFiles(e.Node.Value);
        }

        protected void cViewDirs_NodeSelected(object sender, EventArgs e)
        {
            PopulateFiles(cViewDirs.SelectedNode.Value);
        }


        protected void cTblFiles_ItemDataBound(object sender, DataListItemEventArgs e)
        {
            if ((e.Item.ItemType != ListItemType.Item) && (e.Item.ItemType != ListItemType.AlternatingItem)) { return; }

            string filename = e.Item.DataItem.ToString();
            FileInfo info = new FileInfo(filename);
            Panel cPnl = e.Item.FindControl("cPnl") as Panel;
            ImageButton cImgIcon = e.Item.FindControl("cImgIcon") as ImageButton;
            LinkButton cLnkName = e.Item.FindControl("cLnkName") as LinkButton;
            cPnl.ToolTip = info.Name;
            cImgIcon.ImageUrl = "/FileSystemIcon.axd?extn=" + info.Extension;
            cLnkName.Text = " " + info.Name;
            cLnkName.CommandArgument = info.Name;
            cImgIcon.CommandArgument = info.Name;
            cLnkName.Command += new CommandEventHandler(File_Command);
            cImgIcon.Command += new CommandEventHandler(File_Command);
            if ((info.Attributes & FileAttributes.Compressed) != 0) { cLnkName.ForeColor = System.Drawing.Color.Blue; }
        }

        protected void Page_Command(object sender, CommandEventArgs e)
        {
            string folderPath = string.Empty;

            switch (e.CommandName)
            {
                case "Download":
                    Marbles.Core.Site.FileSystem fs = new Core.Site.FileSystem();
                    fs.Backup(this.Response, "Backup", cLblPath.Text, false);
                    break;
                case "InfoDelete":
                    if (File.Exists(cBtnInfoDelete.CommandArgument.ToString())) { File.Delete(cBtnInfoDelete.CommandArgument.ToString()); }
                    PopulateFiles(cCurrentDir.Value);
                    cBtnInfoDelete.CommandArgument = "";
                    cBtnInfoView.CommandArgument = "";
                    cDlgFileInfo.Visible = false;
                    break;
                case "InfoView":

                    string path = "\\" + e.CommandArgument.ToString().Replace(Request.PhysicalApplicationPath, "").Trim().Replace("\\", "/");
                    cBtnInfoDelete.CommandArgument = "";
                    cBtnInfoView.CommandArgument = "";
                    cDlgFileInfo.Visible = false;
                    Response.Redirect("/Admin/Downloads/Download.aspx?path=" + path, true);
                    break;
                case "InfoClose":
                    cBtnInfoDelete.CommandArgument = "";
                    cBtnInfoView.CommandArgument = "";
                    cDlgFileInfo.Visible = false;
                    break;
                case "Upload":
                    cDlgFileUpload.Visible = true;
                    cLblFileUploadDest.Text = cLblPath.Text;
                    cBtnSave.CommandArgument = cCurrentDir.Value;
                    break;
                case "UploadCreate":
                    if (cFileUpload.HasFile)
                    {
                        string filename = Path.Combine(cBtnSave.CommandArgument.ToString(), cFileUpload.FileName);
                        if (File.Exists(filename)) { File.Delete(filename); }

                        cFileUpload.SaveAs(filename);
                    }                    
                    cBtnSave.CommandArgument = "";
                    cDlgFileUpload.Visible = false;
                    PopulateFiles(cCurrentDir.Value);
                    break;
                case "UploadCancel":
                    cBtnSave.CommandArgument = "";
                    cDlgFileUpload.Visible = false;
                    break;
                case "NewFolder":
                    cDlgNewFolder.Visible = true;
                    cTxtNewFolderName.Text = "";
                    cLblnewFolderParent.Text = cLblPath.Text;
                    cBtnNewFolderCreate.CommandArgument = cLblPath.Text;
                    break;
                case "NewFolderCreate":
                    folderPath = Server.MapPath(cLblnewFolderParent.Text + "/" + cTxtNewFolderName.Text);
                    if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); }
                    cDlgNewFolder.Visible = false;
                    cLblnewFolderParent.Text = "";
                    cBtnNewFolderCreate.CommandArgument = "";
                    InitialiseForm();
                    break;
                case "NewFolderCancel":
                    cDlgNewFolder.Visible = false;
                    cLblnewFolderParent.Text = "";
                    cBtnNewFolderCreate.CommandArgument = "";
                    break;
                case "DeleteFolder":
                    folderPath = Server.MapPath(cLblPath.Text);
                    if (Directory.Exists(folderPath)) { Directory.Delete(folderPath, true); }
                    InitialiseForm();
                    break;
            }
        }
    }
}